<?php
/**
 * Created by PhpStorm.
 * User: xiaomage
 * Date: 2021/1/11
 * Time: 13:39
 */

namespace magein\utils;

use magein\utils\traits\Instance;

class Image
{

    use Instance;

    /**
     * 保存图片的路径
     * @var string
     */
    protected string $save_path = '';

    /**
     * 是否重新命名
     * @var bool
     */
    protected bool $rename = false;

    /**
     * 直接渲染图片
     * @var bool
     */
    protected bool $fetch = false;

    /**
     *  保存路径 文件名称为远程图片名称
     *  ./storage/images
     * @param string $save_path
     * @return Image
     */
    public function setSavePath(string $save_path): Image
    {
        $this->save_path = $save_path;

        if (!is_dir($save_path)) {
            mkdir($save_path, 0777, true);
        }

        return $this;
    }

    /**
     * @param bool $bool
     * @return $this
     */
    public function setFetch(bool $bool = true): Image
    {
        $this->fetch = $bool;

        return $this;
    }

    /**
     * @param $content
     * @param string $filename 保存的文件名称  test、test.png
     * @param bool $cover
     * @return Result
     */
    public function saveBase64($content, string $filename = '', bool $cover = false): Result
    {
        if (empty($content)) {
            return Result::error('图片内容为空');
        }

        preg_match('/^(data:\s*image\/(\w+);base64,)/', $content, $result);
        if (empty($result)) {
            return Result::error('不是合法的base64图片格式');
        }

        $extension = '';
        if ($filename) {
            $extension = pathinfo($filename, PATHINFO_EXTENSION);
        }

        if (empty($extension)) {
            preg_match('/data:image\/(.+);/', $content, $matches);
            $extension = $matches[1] ?? '';
            if ($extension == 'jpeg') {
                $extension = 'jpg';
            }
            $filename = ($filename ?: md5(uniqid())) . '.' . $extension;
        }

        $content = base64_decode(str_replace($result[1], '', $content));

        return $this->save($content, $filename, $cover);
    }

    /**
     * @param $url
     * @param string|null $filename
     * @param array $headers
     * @return Result|void
     */
    public function remote($url, string $filename = null, array $headers = [])
    {
        if (empty($url)) {
            return Result::error('请输入远程图片地址');
        }

        if (!Validator::url($url)) {
            return Result::error('远程图片地址格式错误');
        }

        $timeout = 5;
        if (empty($headers)) {
            $headers = BrowserAgent::header();
        }

        //获取远程文件所采用的方法
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        if (Validator::https($url)) {
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        }
        $data = curl_exec($ch);
        $mime = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
        if (curl_errno($ch)) {
            return Result::error(curl_error($ch));
        }
        curl_close($ch);
        if (!str_contains($mime, 'image')) {
            return Result::error('远程地址mime类型不是图片类型');
        }

        if ($this->fetch) {
            header("content-type:$mime;");
            echo $data;
            exit();
        }

        return $this->save($data, $filename, true);
    }

    /**
     * @param $content
     * @param string|null $filename
     * @param bool $cover
     * @return Result
     */
    protected function save($content, string $filename = null, bool $cover = false): Result
    {
        if (empty($this->save_path)) {
            return Result::error('请设置保存路径');
        }

        $extension = '';
        if ($filename) {
            $extension = pathinfo($filename, PATHINFO_EXTENSION);
        }

        if (empty($extension)) {
            $filename = ($filename ?: md5(uniqid())) . '.png';
        }

        $filepath = trim($this->save_path, '/') . '/' . trim($filename, '/');
        if (is_file($filepath) && !$cover) {
            return Result::error('文件已经存在');
        }

        try {
            file_put_contents($filepath, $content);
        } catch (\Exception $exception) {

        }

        if (is_file($filepath)) {
            return Result::success($filepath);
        }

        return Result::error('文件保存失败:' . $filepath);
    }
}